package application;

import java.awt.TextArea;
import java.io.IOException;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import javafx.beans.value.ObservableValue;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.text.Text;
import jeopardy.common.protocol.game.play.AnswerMsg;
import jeopardy.common.protocol.game.stats.UserScore;

public class GameScreenController implements Initializable , ControlledScreen {

	/* A separate class must exist wit the same name as the TableView name
	 * This allows defines the data to be displayed on the table columns.
	 */
	
	@FXML
    private TableView<GameStats> table;
    @FXML private TableColumn<GameStats, String> colName = new TableColumn<GameStats, String>("Player");
    @FXML private TableColumn<GameStats, String> colScore = new TableColumn<GameStats, String>("Score");
    
    
    private Map<String, Integer> userScore = new HashMap<String, Integer>();
	// @FXML private TextField answerField;
	
	@FXML
	private Text questionField;

	@FXML
	private Text qNumField;
	
	 @FXML
	 TextArea answerField;
	
    ScreensController myController;
    
    private BlockingQueue<AnswerMsg> answerQueue = new LinkedBlockingQueue<AnswerMsg>();
    
    private int numPlayed = 0;
    
    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    	colName.setCellValueFactory(new PropertyValueFactory<GameStats, String>("name"));
        colScore.setCellValueFactory(new PropertyValueFactory<GameStats, String>("score"));
        
        table.getColumns().setAll(colName, colScore);
        
    	Socket sock = null;  //TODO socket should have been created when GameScreen is shown to user;
    	GameScreenLogic gsl = new GameScreenLogic(sock, this, answerQueue);
    	
    }
    
    public void setScreenParent(ScreensController screenParent){
        myController = screenParent;
    }

	// Process submit button action
    @FXML
	private void handleSubmitButtonAction(ActionEvent event) throws UnknownHostException, IOException, Exception {
		AnswerMsg ans = new AnswerMsg(questionField.getText(), answerField.getText());
		answerQueue.offer(ans);
		answerField.setText("");
	}
	
    @FXML
    private void goTowelcome(ActionEvent event){
       myController.setScreen(ScreensFramework.WelcomeScreenID);
    }
    
    @FXML
    private void goToRegistration(ActionEvent event){
       myController.setScreen(ScreensFramework.RegistrationScreenID);
    }

    ////////////////////////    GAME FLOW    //////////////////////////////
    
    
	public void notifyStart(long startsInMilli, String[] players) {
		ObservableList<GameStats> stats = table.getItems();
		for(String player : players){
			userScore.put(player, 0);
			GameStats gs = new GameStats();
			gs.setName(player);
			gs.setScore(0);
			stats.add(gs);
		}
	}

	public void setUsers(String[] eligiblePlayers) {
		
		
		//TODO update the label.  Do we need to make this a three column?
	}

	public void newQuestion(String question, int points, long timeToPlayMillis) {
		numPlayed++;
		qNumField.setText("" + numPlayed);
		questionField.setText("[" + points + "] " + question);
		//TODO show timeToPlayMillis
	}

	public void questionAttempted(String answer, String answerer, long timeTookMilliseconds) {
		// TODO Auto-generated method stub
		
	}

	public void questionAnswered(String answer, String winner, int points, long timeMillis) {
		userScore.put(winner, userScore.get(winner) + points);
		ObservableList<GameStats> stats = table.getItems();
		stats.clear();
		Iterator<String> players = userScore.keySet().iterator();
		while(players.hasNext()){
			GameStats gs = new GameStats();
			gs.setName(players.next());
			gs.setScore(userScore.get(gs.getName()));
			stats.add(gs);
		}
	}

	public void gameFinished(String winner, int pointsWon) {
		//TODO display winner screen	
	}
}
